package com.zhoust.fastdome.aspect;

import com.alibaba.fastjson.JSONObject;
import com.zhoust.fastdome.business.service.CommonLogService;
import com.zhoust.fastdome.common.CommonConstant;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * @author zhoust
 * @Date 2021/9/22 22:52
 * @Desc AOP + 包扫描记录日志
 */
@Slf4j
@Aspect
@Component
public class LogAspectByScanPackage {

    @Value("${fast.dome.logType}")
    private String logType;

    private final CommonLogService commonLogService;
    final HttpServletRequest request;


    public LogAspectByScanPackage(CommonLogService commonLogService,HttpServletRequest request) {
        this.commonLogService = commonLogService;
        this.request = request;
    }
    /**
     * 1、execution(): 表达式主体。
     * 2、第一个*号：表示返回类型， *号表示所有的类型。
     * 3、包名：表示需要拦截的包名，后面的两个句点表示当前包和当前包的所有子包，com.zhoust.fastdome.business.controller.scan包、子孙包下所有类的方法。
     * 4、第二个*号：表示类名，*号表示所有的类。
     * 5、*(..):最后这个星号表示方法名，*号表示所有的方法，后面括弧里面表示方法的参数，两个句点表示任何参数
     */
    @Pointcut("execution(* com.zhoust.fastdome.business.controller.scan.*.*(..))")
    public void getPointCutByScanPackage(){
    }

    @Around("getPointCutByScanPackage()")
    public Object saveLog(ProceedingJoinPoint joinPoint) throws Throwable {

        if(!CommonConstant.aopPackage.equals(logType)){
            return joinPoint.proceed();
        }
        log.info("=================包扫描记录日志==========================");
        Object result = "";
        // 执行目标 获取返回值
        try {
            result = joinPoint.proceed();
            commonLogService.saveLog(JSONObject.toJSONString(result),joinPoint);
        } catch (Throwable throwable) {
            log.error("执行方法失败,没有记录返回报文，不报错,异常信息：{}",throwable);
            // 手动抛出异常，便于统一处理拦截
            throw throwable;
        }
        return result;
    }
}
